import { 
  STORAGE_KEYS, 
  DATA_VERSION, 
  DATA_MIGRATION, 
  STORAGE_CONFIG, 
  STORAGE_ERROR_CODES, 
  STORAGE_EVENTS,
  type StorageKey,
  type StorageErrorCode,
  type StorageEvent
} from '@/constants/storage';
import { LocalStorageUtils, type IStorageResult } from '@/utils/storage/localStorage';
import { SessionStorageUtils } from '@/utils/storage/sessionStorage';
import type { IBaseEntity, OperationResult } from '@/types/common/base';

/**
 * 数据迁移接口
 * @description 定义数据迁移的结构
 */
export interface IDataMigration {
  /** 源版本 */
  fromVersion: string;
  /** 目标版本 */
  toVersion: string;
  /** 迁移函数 */
  migrate: (data: unknown) => Promise<unknown>;
  /** 迁移描述 */
  description: string;
}

/**
 * 存储服务配置接口
 */
export interface IStorageServiceConfig {
  /** 是否启用自动备份 */
  autoBackup: boolean;
  /** 备份间隔（毫秒） */
  backupInterval: number;
  /** 最大备份数量 */
  maxBackups: number;
  /** 是否启用数据压缩 */
  compression: boolean;
  /** 是否启用数据校验 */
  dataValidation: boolean;
}

/**
 * 备份信息接口
 */
export interface IBackupInfo {
  /** 备份ID */
  id: string;
  /** 备份时间戳 */
  timestamp: number;
  /** 数据版本 */
  version: string;
  /** 备份大小（字节） */
  size: number;
  /** 备份描述 */
  description?: string;
  /** 是否为自动备份 */
  isAutoBackup: boolean;
}

/**
 * 存储统计信息接口
 */
export interface IStorageServiceStats {
  /** 总存储项数量 */
  totalItems: number;
  /** 已使用存储空间（字节） */
  usedSpace: number;
  /** 可用存储空间（字节） */
  availableSpace: number;
  /** 备份数量 */
  backupCount: number;
  /** 最后备份时间 */
  lastBackupTime: number | null;
  /** 最后清理时间 */
  lastCleanupTime: number | null;
  /** 数据版本 */
  dataVersion: string;
}

/**
 * 存储服务类
 * @description 提供统一的数据存储、版本管理、迁移和备份功能
 */
export class StorageService {
  private config: IStorageServiceConfig;
  private migrations: Map<string, IDataMigration[]> = new Map();
  private backupTimer: number | null = null;

  constructor(config: Partial<IStorageServiceConfig> = {}) {
    this.config = {
      autoBackup: STORAGE_CONFIG.BACKUP.AUTO_BACKUP_ENABLED,
      backupInterval: STORAGE_CONFIG.BACKUP.BACKUP_INTERVAL,
      maxBackups: STORAGE_CONFIG.BACKUP.MAX_BACKUP_COUNT,
      compression: STORAGE_CONFIG.BACKUP.COMPRESSION_ENABLED,
      dataValidation: true,
      ...config
    };

    this.initializeMigrations();
    this.initializeAutoBackup();
    this.initializeEventListeners();
  }

  /**
   * 存储数据
   * @param key 存储键
   * @param data 数据
   * @param options 存储选项
   * @returns 操作结果
   */
  async setItem<T = unknown>(
    key: StorageKey, 
    data: T, 
    options: {
      /** 过期时间（毫秒） */
      expiresIn?: number;
      /** 是否跳过验证 */
      skipValidation?: boolean;
      /** 是否创建备份 */
      createBackup?: boolean;
    } = {}
  ): Promise<OperationResult<T>> {
    try {
      // 数据验证
      if (this.config.dataValidation && !options.skipValidation) {
        const validationResult = this.validateData(data);
        if (!validationResult.success) {
          return validationResult;
        }
      }

      // 创建备份（如果需要）
      if (options.createBackup) {
        await this.createBackup(`手动备份 - ${key}`);
      }

      // 存储数据
      const result = LocalStorageUtils.setItem(key, data, {
        expiresIn: options.expiresIn,
        type: this.getDataType(key),
        compress: this.config.compression
      });

      if (!result.success) {
        return {
          success: false,
          error: result.errorMessage || '存储数据失败',
          errorCode: result.errorCode
        };
      }

      // 更新数据版本
      await this.updateDataVersion();

      return {
        success: true,
        data
      };

    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : '存储数据时发生未知错误';
      return {
        success: false,
        error: errorMessage,
        errorCode: STORAGE_ERROR_CODES.UNKNOWN_ERROR
      };
    }
  }

  /**
   * 获取数据
   * @param key 存储键
   * @param options 获取选项
   * @returns 操作结果
   */
  async getItem<T extends NonNullable<unknown> = Record<string, unknown>>(
    key: StorageKey,
    options: {
      /** 是否自动迁移数据 */
      autoMigrate?: boolean;
      /** 是否跳过验证 */
      skipValidation?: boolean;
    } = {}
  ): Promise<OperationResult<T>> {
    try {
      const result = LocalStorageUtils.getItem<T>(key);

      if (!result.success) {
        return {
          success: false,
          error: result.errorMessage || '获取数据失败',
          errorCode: result.errorCode
        };
      }

      let data = result.data!;

      // 自动迁移数据（如果需要）
      if (options.autoMigrate !== false) {
        const migrationResult = await this.migrateDataIfNeeded(key, data);
        if (migrationResult.success && migrationResult.data !== undefined) {
          data = migrationResult.data as T;
        }
      }

      // 数据验证
      if (this.config.dataValidation && !options.skipValidation) {
        const validationResult = this.validateData(data);
        if (!validationResult.success) {
          return validationResult;
        }
      }

      return {
        success: true,
        data
      };

    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : '获取数据时发生未知错误';
      return {
        success: false,
        error: errorMessage,
        errorCode: STORAGE_ERROR_CODES.UNKNOWN_ERROR
      };
    }
  }

  /**
   * 删除数据
   * @param key 存储键
   * @param options 删除选项
   * @returns 操作结果
   */
  async removeItem(
    key: StorageKey,
    options: {
      /** 是否创建备份 */
      createBackup?: boolean;
    } = {}
  ): Promise<OperationResult<void>> {
    try {
      // 创建备份（如果需要）
      if (options.createBackup) {
        await this.createBackup(`删除前备份 - ${key}`);
      }

      const result = LocalStorageUtils.removeItem(key);

      if (!result.success) {
        return {
          success: false,
          error: result.errorMessage || '删除数据失败',
          errorCode: result.errorCode
        };
      }

      return {
        success: true,
        data: undefined
      };

    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : '删除数据时发生未知错误';
      return {
        success: false,
        error: errorMessage,
        errorCode: STORAGE_ERROR_CODES.UNKNOWN_ERROR
      };
    }
  }

  /**
   * 清空所有数据
   * @param options 清空选项
   * @returns 操作结果
   */
  async clear(
    options: {
      /** 是否创建备份 */
      createBackup?: boolean;
      /** 是否保留系统数据 */
      preserveSystemData?: boolean;
    } = {}
  ): Promise<OperationResult<void>> {
    try {
      // 创建备份（如果需要）
      if (options.createBackup) {
        await this.createBackup('清空前完整备份');
      }

      if (options.preserveSystemData) {
        // 只清空业务数据，保留系统数据
        const businessKeys = [
          STORAGE_KEYS.STUDENTS,
          STORAGE_KEYS.COURSES,
          STORAGE_KEYS.COURSE_CATEGORIES,
          STORAGE_KEYS.SCHEDULE_TEMPLATES,
          STORAGE_KEYS.SCHEDULE_INSTANCES
        ];

        for (const key of businessKeys) {
          await this.removeItem(key);
        }
      } else {
        // 清空所有数据
        const result = LocalStorageUtils.clear();
        if (!result.success) {
          return {
            success: false,
            error: result.errorMessage || '清空数据失败',
            errorCode: result.errorCode
          };
        }
      }

      return {
        success: true,
        data: undefined
      };

    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : '清空数据时发生未知错误';
      return {
        success: false,
        error: errorMessage,
        errorCode: STORAGE_ERROR_CODES.UNKNOWN_ERROR
      };
    }
  }

  /**
   * 创建数据备份
   * @param description 备份描述
   * @returns 操作结果
   */
  async createBackup(description?: string): Promise<OperationResult<IBackupInfo>> {
    try {
      const backupId = this.generateBackupId();
      const timestamp = Date.now();
      
      // 收集所有业务数据
      const backupData: Record<string, unknown> = {};
      const businessKeys = [
        STORAGE_KEYS.STUDENTS,
        STORAGE_KEYS.COURSES,
        STORAGE_KEYS.COURSE_CATEGORIES,
        STORAGE_KEYS.SCHEDULE_TEMPLATES,
        STORAGE_KEYS.SCHEDULE_INSTANCES,
        STORAGE_KEYS.APP_SETTINGS,
        STORAGE_KEYS.USER_PREFERENCES
      ];

      for (const key of businessKeys) {
        const result = LocalStorageUtils.getItem(key);
        if (result.success) {
          backupData[key] = result.data;
        }
      }

      // 创建备份信息
      const backupInfo: IBackupInfo = {
        id: backupId,
        timestamp,
        version: DATA_VERSION.CURRENT,
        size: new Blob([JSON.stringify(backupData)]).size,
        description: description || `自动备份 ${new Date(timestamp).toLocaleString()}`,
        isAutoBackup: !description
      };

      // 存储备份数据
      const backupKey = `${STORAGE_KEYS.BACKUP_PREFIX}${backupId}`;
      const backupResult = LocalStorageUtils.setItem(backupKey, {
        info: backupInfo,
        data: backupData
      }, {
        expiresIn: -1, // 备份永不过期
        compress: this.config.compression
      });

      if (!backupResult.success) {
        return {
          success: false,
          error: backupResult.errorMessage || '创建备份失败',
          errorCode: backupResult.errorCode
        };
      }

      // 清理旧备份
      await this.cleanupOldBackups();

      // 触发备份创建事件
      this.dispatchEvent(STORAGE_EVENTS.BACKUP_CREATED, backupInfo);

      return {
        success: true,
        data: backupInfo
      };

    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : '创建备份时发生未知错误';
      return {
        success: false,
        error: errorMessage,
        errorCode: STORAGE_ERROR_CODES.BACKUP_FAILED
      };
    }
  }

  /**
   * 恢复数据备份
   * @param backupId 备份ID
   * @returns 操作结果
   */
  async restoreBackup(backupId: string): Promise<OperationResult<void>> {
    try {
      const backupKey = `${STORAGE_KEYS.BACKUP_PREFIX}${backupId}`;
      const backupResult = LocalStorageUtils.getItem<{
        info: IBackupInfo;
        data: Record<string, unknown>;
      }>(backupKey);

      if (!backupResult.success) {
        return {
          success: false,
          error: '备份数据不存在或已损坏',
          errorCode: STORAGE_ERROR_CODES.INVALID_DATA_FORMAT
        };
      }

      const { info, data } = backupResult.data!;

      // 创建当前数据的备份
      await this.createBackup(`恢复前备份 - ${new Date().toLocaleString()}`);

      // 恢复数据
      for (const [key, value] of Object.entries(data)) {
        if (value !== null && value !== undefined) {
          const result = LocalStorageUtils.setItem(key as StorageKey, value, {
            expiresIn: -1,
            compress: this.config.compression
          });

          if (!result.success) {
            console.warn(`恢复数据失败: ${key}`, result.errorMessage);
          }
        }
      }

      // 更新数据版本
      await this.updateDataVersion(info.version);

      // 触发数据恢复事件
      this.dispatchEvent(STORAGE_EVENTS.DATA_RESTORED, { backupId, info });

      return {
        success: true,
        data: undefined
      };

    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : '恢复备份时发生未知错误';
      return {
        success: false,
        error: errorMessage,
        errorCode: STORAGE_ERROR_CODES.RESTORE_FAILED
      };
    }
  }

  /**
   * 获取所有备份信息
   * @returns 备份信息列表
   */
  async getBackups(): Promise<OperationResult<IBackupInfo[]>> {
    try {
      const backups: IBackupInfo[] = [];
      const keys = LocalStorageUtils.getKeys(STORAGE_KEYS.BACKUP_PREFIX);

      for (const key of keys) {
        const result = LocalStorageUtils.getItem<{
          info: IBackupInfo;
          data: Record<string, unknown>;
        }>(key);

        if (result.success && result.data?.info) {
          backups.push(result.data.info);
        }
      }

      // 按时间戳降序排序
      backups.sort((a, b) => b.timestamp - a.timestamp);

      return {
        success: true,
        data: backups
      };

    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : '获取备份列表时发生未知错误';
      return {
        success: false,
        error: errorMessage,
        errorCode: STORAGE_ERROR_CODES.UNKNOWN_ERROR
      };
    }
  }

  /**
   * 删除备份
   * @param backupId 备份ID
   * @returns 操作结果
   */
  async deleteBackup(backupId: string): Promise<OperationResult<void>> {
    try {
      const backupKey = `${STORAGE_KEYS.BACKUP_PREFIX}${backupId}`;
      const result = LocalStorageUtils.removeItem(backupKey);

      if (!result.success) {
        return {
          success: false,
          error: result.errorMessage || '删除备份失败',
          errorCode: result.errorCode
        };
      }

      return {
        success: true,
        data: undefined
      };

    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : '删除备份时发生未知错误';
      return {
        success: false,
        error: errorMessage,
        errorCode: STORAGE_ERROR_CODES.UNKNOWN_ERROR
      };
    }
  }

  /**
   * 获取存储统计信息
   * @returns 统计信息
   */
  async getStats(): Promise<IStorageServiceStats> {
    const localStats = LocalStorageUtils.getStats();
    const backupsResult = await this.getBackups();
    const dataVersionResult = LocalStorageUtils.getItem<string>(STORAGE_KEYS.DATA_VERSION);

    return {
      totalItems: localStats.itemCount,
      usedSpace: localStats.usedSpace,
      availableSpace: localStats.totalSpace - localStats.usedSpace,
      backupCount: backupsResult.success ? backupsResult.data!.length : 0,
      lastBackupTime: backupsResult.success && backupsResult.data!.length > 0 
        ? backupsResult.data![0].timestamp 
        : null,
      lastCleanupTime: localStats.lastCleanupTime,
      dataVersion: dataVersionResult.success ? dataVersionResult.data! : DATA_VERSION.DEFAULT
    };
  }

  /**
   * 清理过期数据和缓存
   * @returns 操作结果
   */
  async cleanup(): Promise<OperationResult<{ removedCount: number; freedSpace: number }>> {
    try {
      // 清理过期的本地存储数据
      const localCleanupResult = LocalStorageUtils.cleanup();
      
      if (!localCleanupResult.success) {
        return {
          success: false,
          error: localCleanupResult.errorMessage || '清理数据失败',
          errorCode: localCleanupResult.errorCode
        };
      }

      // 清理旧备份
      await this.cleanupOldBackups();

      return {
        success: true,
        data: localCleanupResult.data!
      };

    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : '清理数据时发生未知错误';
      return {
        success: false,
        error: errorMessage,
        errorCode: STORAGE_ERROR_CODES.UNKNOWN_ERROR
      };
    }
  }

  /**
   * 销毁服务实例
   */
  destroy(): void {
    if (this.backupTimer) {
      window.clearInterval(this.backupTimer);
      this.backupTimer = null;
    }
  }

  /**
   * 初始化数据迁移规则
   */
  private initializeMigrations(): void {
    // 这里可以添加具体的数据迁移规则
    // 例如：从 1.0.0 到 1.1.0 的迁移
    // this.addMigration({
    //   fromVersion: '1.0.0',
    //   toVersion: '1.1.0',
    //   migrate: async (data) => {
    //     // 迁移逻辑
    //     return data;
    //   },
    //   description: '添加新字段支持'
    // });
  }

  /**
   * 初始化自动备份
   */
  private initializeAutoBackup(): void {
    if (this.config.autoBackup && this.config.backupInterval > 0) {
      this.backupTimer = window.setInterval(async () => {
        await this.createBackup();
      }, this.config.backupInterval);
    }
  }

  /**
   * 初始化事件监听器
   */
  private initializeEventListeners(): void {
    // 监听存储空间警告
    LocalStorageUtils.addEventListener(STORAGE_EVENTS.QUOTA_WARNING, () => {
      this.cleanup();
    });
  }

  /**
   * 验证数据格式
   * @param data 数据
   * @returns 验证结果
   */
  private validateData<T = unknown>(data: T): OperationResult<T> {
    // 跳过数据验证，因为不是所有数据都是 IBaseEntity 类型
    // 如果需要验证特定类型的数据，应该在具体的服务中进行

    return {
      success: true,
      data
    };
  }

  /**
   * 获取数据类型
   * @param key 存储键
   * @returns 数据类型
   */
  private getDataType(key: StorageKey): string {
    const typeMap: Record<string, string> = {
      [STORAGE_KEYS.STUDENTS]: 'student',
      [STORAGE_KEYS.COURSES]: 'course',
      [STORAGE_KEYS.COURSE_CATEGORIES]: 'course_category',
      [STORAGE_KEYS.SCHEDULE_TEMPLATES]: 'schedule_template',
      [STORAGE_KEYS.SCHEDULE_INSTANCES]: 'schedule_instance',
      [STORAGE_KEYS.APP_SETTINGS]: 'app_settings',
      [STORAGE_KEYS.USER_PREFERENCES]: 'user_preferences'
    };

    return typeMap[key] || 'unknown';
  }

  /**
   * 更新数据版本
   * @param version 版本号
   */
  private async updateDataVersion(version: string = DATA_VERSION.CURRENT): Promise<void> {
    LocalStorageUtils.setItem(STORAGE_KEYS.DATA_VERSION, version, {
      expiresIn: -1
    });
  }

  /**
   * 迁移数据（如果需要）
   * @param key 存储键
   * @param data 数据
   * @returns 迁移结果
   */
  private async migrateDataIfNeeded<T>(key: StorageKey, data: T): Promise<OperationResult<T>> {
    // 这里可以实现具体的数据迁移逻辑
    // 目前返回原数据
    return {
      success: true,
      data
    };
  }

  /**
   * 清理旧备份
   */
  private async cleanupOldBackups(): Promise<void> {
    const backupsResult = await this.getBackups();
    if (!backupsResult.success) return;

    const backups = backupsResult.data!;
    if (backups.length <= this.config.maxBackups) return;

    // 删除超出数量限制的旧备份
    const backupsToDelete = backups.slice(this.config.maxBackups);
    for (const backup of backupsToDelete) {
      await this.deleteBackup(backup.id);
    }
  }

  /**
   * 生成备份ID
   * @returns 备份ID
   */
  private generateBackupId(): string {
    const timestamp = Date.now().toString(36);
    const randomStr = Math.random().toString(36).substr(2, 9);
    return `backup_${timestamp}_${randomStr}`;
  }

  /**
   * 触发事件
   * @param eventType 事件类型
   * @param detail 事件详情
   */
  private dispatchEvent(eventType: StorageEvent, detail: unknown): void {
    const event = new CustomEvent(eventType, { detail });
    window.dispatchEvent(event);
  }
}

/**
 * 默认存储服务实例
 */
export const storageService = new StorageService();